/*
*    Qizx/open 3.0 beta
*
* This code is the open-source version of Qizx.
* Copyright (C) 2004-2009 Axyana Software -- All rights reserved.
*
* The contents of this file are subject to the Mozilla Public License 
*  Version 1.1 (the "License"); you may not use this file except in 
*  compliance with the License. You may obtain a copy of the License at
*  http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
*  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
*  for the specific language governing rights and limitations under the
*  License.
*
* The Initial Developer of the Original Code is Xavier Franc - Axyana Software.
*
*/
using System;
using EvaluationException = System.Qizx.Api.EvaluationException;
using ModuleContext = System.Qizx.XQuery.ModuleContext;
using XQItem = System.Qizx.XQuery.XQItem;
using XQItemType = System.Qizx.XQuery.XQItemType;
using XQType = System.Qizx.XQuery.XQType;
namespace System.Qizx.XQuery.Op {

    /// <summary> class NumericOp:</summary>
    public abstract class NumericOp : Expression {
        public Expression[] operands;

        public NumericOp(Expression expr1, Expression expr2) {
            operands = new Expression[] { expr1, expr2 };
        }

        public override Expression Child(int rank) {
            return rank < 2 ? operands[rank] : null;
        }

        // public Expression staticCheck( ModuleContext context ) {
        // operands[0] = context.staticCheck(operands[0], 0);
        // operands[1] = context.staticCheck(operands[1], 0);
        // return context.resolve(getProtos(), operands, this );
        // }

        // Static analysis of operands, then combine type codes.
        protected internal virtual int combinedArgTypes(ModuleContext context) {
            operands[0] = context.staticCheck(operands[0], 0);
            operands[1] = context.staticCheck(operands[1], 0);
            XQItemType t1 = operands[0].getType().itemType();
            XQItemType t2 = operands[1].getType().itemType();
            int qt1 = t1.quickCode(), qt2 = t2.quickCode();
#if ! XBRLFormula
            if (qt1 == XQType.QT_UNTYPED)
                qt1 = XQType.QT_DOUBLE;
            if (qt2 == XQType.QT_UNTYPED)
                qt2 = XQType.QT_DOUBLE;
#endif
            return combinedTypes(qt1, qt2);
        }

        // Dynamic analysis of actual operands, then combine type codes.
        protected internal static int combinedArgTypes(XQItem op1, XQItem op2) {
            XQItemType t1 = op1.ItemType;
            XQItemType t2 = op2.ItemType;
            int qt1 = t1.quickCode(), qt2 = t2.quickCode();

#if ! XBRLFormula
			if (qt1 == XQType.QT_UNTYPED)
				qt1 = XQType.QT_DOUBLE;
			if (qt2 == XQType.QT_UNTYPED)
				qt2 = XQType.QT_DOUBLE;
#endif

            return combinedTypes(qt1, qt2);

        }
    }
}